/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#ifndef LIB2D_GUI_SCROLLBAR_H
#define LIB2D_GUI_SCROLLBAR_H

#include "Object.h"
#include "Button.h"
#include "view/ScrollBar.h"
#include <math/utl.h>
#include <xml/Object.h>

namespace liba
{
namespace lib2d
{
namespace gui
{
class ScrollBar;
namespace scrollbar
{

class TopButton: public Button
{
	double next_event_time;
	ScrollBar * scroll_bar;
public:
	TopButton( ScrollBar * parent );
	virtual void on_button_down( const Vector2 & point, const Atom & button_name );
	virtual void life_cycle( double delta_time );
	void layout()
	{
		window_rect = Rect( 0, 0, view->get_width(), view->get_height() );
	}
};

class BottomButton : public Button
{
	double next_event_time;
	ScrollBar * scroll_bar;
public:
	BottomButton( ScrollBar * parent );
	virtual void on_button_down( const Vector2 & point, const Atom & button_name );
	virtual void life_cycle( double delta_time );
	void layout()
	{
		window_rect = Rect( 0, get_parent()->get_window_rect().height - view->get_height(), view->get_width(), view->get_height() );
	}
};

class CenterButton;

} //namespace scrollbar

class ScrollBar :
	public Object,
	private xml::ObjectANSI
{
	scrollbar::TopButton * top;
	scrollbar::BottomButton * bottom;
	scrollbar::CenterButton * center;

	AutoPtr< view::ScrollBar > view;

	friend class view::ScrollBar;
public:
	ScrollBar( Object * parent );

	virtual view::ScrollBar * get_view()const
	{
		return view;
	}

	virtual bool on_attribute( xml::Provider * prov, const std::string & name, const std::string & value );
	virtual bool on_node( xml::Provider * prov, const std::string & name );

	virtual void on_button_down( const Vector2 & point, const Atom & button_name );
	
	virtual void layout();

	Rect get_center_button_area()const
	{
		return Rect( 0, top->get_window_rect().height, window_rect.width, window_rect.height - top->get_window_rect().height - bottom->get_window_rect().height );
	}
	void set_range( double min, double max )
	{
		this->min = min;
		this->max = max;
		pos = min;
		layout();
	}
	void set_position( double pos )
	{
		pos = math::clamp( pos, min, max );
		this->pos = pos;
		layout();
	}
	double get_position()const
	{
		return pos;
	}
	void set_page_size( double page_size )
	{
		page_size = math::clamp( page_size, 0.15, 1.0 );
		this->page_size = page_size;
		layout();
	}
	void set_step( double new_step )
	{
		step = new_step;
	}
	double get_step()const
	{
		return step;
	}
	void update_position();

protected:
    double page_size;
	double min;
	double max;
	double pos;
	double step;
	double page_step;
};

namespace scrollbar
{

class CenterButton : public Button
{
	ScrollBar * scroll_bar;
public:
	CenterButton( ScrollBar * parent )
	:	Button( parent ),
		scroll_bar( parent )
	{}
	void layout( double y, double height )
	{
		window_rect = Rect( 0, y, get_parent()->get_window_rect().width, height );
	}
	virtual void on_mouse_move_outside( const Vector2 & point );
	virtual void on_mouse_out();
	virtual void on_button_up( const Vector2 & point, const Atom & button_name );
	virtual void on_mouse_move( const Vector2 & point );
	virtual void on_button_down( const Vector2 & point, const Atom & button_name );
private:
	Vector2 track_mouse_point;
};
}

} //namespace gui
} //namespace lib2d
} //namespace liba

using namespace liba;

#endif //LIB2D_GUI_SCROLLBAR_H
